
cc.Class({
    extends: cc.Component,

    properties: {
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    start () {

    },

    // update (dt) {},

    GET_CARDS_SUM:function(cards) {
        let sum = 0
        for (let card of cards) {
            let pokerId = card.poker

            if (cc.gg.dataMgr.isMixCard(pokerId))
                sum += 0
            else
                sum += cc.gg.dataMgr.getPokerScore(pokerId)
        }

        return sum
    },

    IS_SEQUENCE:function(cards, mixNum) {
        let cardVals = cc.gg.gameDataUtil.getCardValArrayFromPokerObj(cards)
        return this.IS_SEQUENCE_ONLY_VALUE(cardVals,mixNum)


        // if (cards.length < 3 || cards.length > 13) return {};
        // let _same_cards = [];
        // let _same_card_nums = [];
        // let _jokers = []
        // let is_pure = true
        // let ca = 0
        // for (let card of cards) {
        //     let num = cc.gg.dataMgr.getPokerNum(card.poker)
        //     if (cc.gg.dataMgr.isJokerPoint(num) || num === mixNum) _jokers.push(card);
        //     else {
        //         _same_cards.push(card.poker);
        //         _same_card_nums.push(num);
        //         if(num === 1) ca++
        //     }
        // }
        //
        // let _joker_num = _jokers.length
        // let color = (cc.gg.dataMgr.getPokerHua(_same_cards[0]))
        //
        // if (_same_cards.length < 2) {
        //     return {
        //         isSequence:true,
        //         isPure:false
        //     };
        // }
        //
        // for (let i = 1; i < _same_cards.length; i++) {
        //     if (cc.gg.dataMgr.getPokerHua(_same_cards[i]) != color) return {}
        // }
        //
        // for (let i = 1; i < _jokers.length; i++) {
        //     if (cc.gg.dataMgr.getPokerHua(_jokers[i]) != color){
        //         is_pure = false
        //         break
        //     }
        // }
        //
        // _same_cards.sort((a, b) => a - b)
        // if(ca){
        //     let _cards_no_1 = [].concat(_same_card_nums)
        //     _cards_no_1.remove(1)
        //     _cards_no_1.push(14)
        //     _cards_no_1.sort((a, b) => a - b)
        //
        //     if(this.GET_BROKEN_TIMES(_same_cards) > this.GET_BROKEN_TIMES(_cards_no_1)){
        //         _same_cards = _cards_no_1
        //     }
        // }
        //
        // for (let i = 1; i < _same_cards.length; i++) {
        //     let dif = _same_cards[i] - _same_cards[i - 1];
        //
        //     if (dif === 0) return {}
        //     if (dif > 1 && _jokers.length === 0) return {};
        //
        //     if(dif > 1) {
        //         if(is_pure && !this.GET_POKER_FROM_ARRAY(_jokers,_same_cards[i - 1] + 1)){
        //             is_pure = false
        //         }
        //
        //         _joker_num -= dif - 1
        //         if(_joker_num < 0) return {}
        //     }
        // }
        //
        // if(is_pure && _joker_num > 0){
        //     is_pure = false
        // }
        //
        // return {
        //     isSequence:true,
        //     isPure:is_pure
        // };
    },

    IS_SEQUENCE_ONLY_VALUE:function(cards, mixNum) {
        if (cards.length < 3 || cards.length > 13) return {};
        let _same_cards = [];
        let _same_card_nums = [];
        let _jokers = []
        let is_pure = true
        let ca = 0
        for (let card of cards) {
            let num = cc.gg.dataMgr.getPokerNum(card)
            if (cc.gg.dataMgr.isJokerPoint(num)){
                _jokers.push(card)
            }else if(num === mixNum){
                _jokers.push(card)
                if(num === 1) ca++
            }else {
                _same_cards.push(card);
                _same_card_nums.push(num);
                if(num === 1) ca++
            }
        }

        let firstPoker = _same_cards[0]
        let color = (cc.gg.dataMgr.getPokerHua(firstPoker))

        if (_same_cards.length < 2) {
            return {
                isSequence:true,
                isPure:false
            };
        }

        //check same color
        for (let i = 1; i < _same_cards.length; i++) {
            if (cc.gg.dataMgr.getPokerHua(_same_cards[i]) != color) return {}
        }

        for (let i = 0; i < _jokers.length; i++) {
            if (cc.gg.dataMgr.getPokerHua(_jokers[i]) != color){
                is_pure = false
                break
            }
        }

        //now we can know that jokers is all same color with not-mix cards
        //check if can mix aside
        // let no_mix_cards = [].concat(_same_cards).concat(_jokers)
        // no_mix_cards.sort((a, b) => a - b)
        if(this._CHECK_SEQUENCE_SIMPLE(color,_same_cards,_jokers)) return {isSequence:true,isPure:true}

        if(ca){
            let _cards_no_1 = [].concat(_same_card_nums)
            cc.gg.baseUtil.arrayRemove(_cards_no_1,1)
            _cards_no_1.push(14)
            _cards_no_1.sort((a, b) => a - b)

            let _ori_broken_count = this.GET_BROKEN_TIMES(_same_cards)
            let _with14_broken_count = this.GET_BROKEN_TIMES(_cards_no_1)
            if(_ori_broken_count > _with14_broken_count){
                _same_cards = _cards_no_1
            }else if(_with14_broken_count === 0){
                return {isSequence:true,isPure:is_pure}
            }
        }

        //以下的逻辑无需考虑花色
        _same_cards.sort((a, b) => a - b)
        for (let i = 1; i < _same_cards.length; i++) {
            let dif = _same_cards[i] - _same_cards[i - 1];

            if (dif === 0) return {}
            if (dif > 1 && _jokers.length === 0) return {};

            let _mixed_count = 0
            if(dif > 1 && is_pure){
                for(let j = 1;j < dif;j++){
                    let lack_card = cc.gg.dataMgr.getCardId(color,cc.gg.dataMgr.getPokerNum(_same_cards[i-1]) + j)
                    let mix_idx = _jokers.indexOf(lack_card)
                    if(mix_idx > -1){
                        _jokers.splice(mix_idx,1)
                        _mixed_count++
                    }else{
                        is_pure = false
                        break
                    }
                }
            }
            dif -= _mixed_count

            if(dif > 1) {
                if(is_pure && !this.GET_POKER_FROM_ARRAY(_jokers,_same_cards[i - 1] + 1)){
                    is_pure = false
                }

                if(_jokers.length === 0) return {}
                for(let j=0;j<dif - 1;j++) {
                    _jokers.splice(0,1)
                    if(_jokers.length === 0 && j !== dif-1-1)
                        return { isSequence:false, isPure:is_pure }
                }
            }
        }

        let colorHex = this._GET_COLOR_HEX(_same_cards[0])
        let _same_hua_jokers = this._GET_ARRAY_BY_COLOR(_jokers,colorHex)
        if(is_pure && _jokers.length > 0 && !this._IS_ALL_NEXT(_same_cards,_same_hua_jokers)){
            is_pure = false
        }

        return {
            isSequence:true,
            isPure:is_pure
        };
    },

    _GET_COLOR_HEX:function (poker) {
        let hua = poker >> 4
        hua = hua << 4
        let colorHex = hua
        return colorHex
    },

    _GET_ARRAY_BY_COLOR:function (ori_array, color) {
        let newArray = []
        for(let i=0;i<ori_array.length;i++){
            let num = cc.gg.dataMgr.getPokerNum(ori_array[i])
            let poker = this._GENERATE_POKER(color,num)
            newArray.push(poker)
        }
        return newArray
    },

    _GENERATE_POKER(color,number){
        return color | number
    },

    //seq_cards must be sorted,top is smaller
    _IS_ALL_NEXT:function (seq_cards, _jokers) {
        seq_cards = [].concat(seq_cards)
        _jokers = [].concat(_jokers)

        // cc.log("检查是否混子都能好好地放到两边之前",seq_cards)
        this._CHECK_ALL_NEXT(seq_cards,_jokers)
        // cc.log("检查是否混子都能好好地放到两边",seq_cards)
        if(_jokers.length){
            return false
        }else return true
    },

    _CHECK_ALL_NEXT:function (seq_cards, _jokers) {
        let seq_top = seq_cards[0]
        let seq_tail = seq_cards[seq_cards.length - 1]
        for(let j = 0;j< _jokers.length ; j++){
            let _tmp_joker = _jokers[j]
            if(_tmp_joker === seq_top - 1){
                _jokers.splice(j--,1)
                seq_cards.unshift(_tmp_joker)
                return this._CHECK_ALL_NEXT(seq_cards,_jokers)
            }else if(_tmp_joker === seq_tail + 1){
                _jokers.splice(j--,1)
                seq_cards.push(_tmp_joker)
                return this._CHECK_ALL_NEXT(seq_cards,_jokers)
            }
        }
    },

    //same_color_cards must be sort before
    _CHECK_SEQUENCE_SIMPLE:function (seq_color,_same_cards,_jokers) {

        //check jokers color
        for(let i=0;i<_jokers.length;i++){
            let _joker_value = _jokers[i]
            let _color = cc.gg.dataMgr.getPokerHua(_joker_value)
            if(_color !== seq_color) return false
        }

        let no_mix_cards = [].concat(_same_cards).concat(_jokers)
        no_mix_cards.sort((a, b) => a - b)

        let _has_a = false
        for(let i=0;i<no_mix_cards.length;i++){
            let _value = no_mix_cards[i]
            let num = cc.gg.dataMgr.getPokerNum(_value)
            if(num === 1){
                _has_a = true
                break
            }
        }

        if(_has_a){
            let _cards_no_1 = [].concat(no_mix_cards)
            cc.gg.baseUtil.arrayRemove(_cards_no_1,1)
            _cards_no_1.push(14)
            _cards_no_1.sort((a, b) => a - b)
            return this._DO_CHECK_SIMPLE(_cards_no_1)
        }

        return this._DO_CHECK_SIMPLE(no_mix_cards)
    },

    _DO_CHECK_SIMPLE:function (no_mix_cards) {
        for (let i = 1; i < no_mix_cards.length; i++) {
            let dif = no_mix_cards[i] - no_mix_cards[i - 1];

            if (dif === 1) continue
            if (dif > 1) return false
            if (dif === 0) return false
        }

        return true
    },

    GET_POKER_FROM_ARRAY:function (fromArray, number) {
        for(let i=0;i<fromArray.length;i++){
            if(cc.gg.dataMgr.getPokerNum(fromArray[i].poker) === number){
                return true
            }
        }

        return false
    },

    //param array must be sorted
    GET_BROKEN_TIMES:function (_same_cards) {
        let empty_place = 0
        for (let i = 1; i < _same_cards.length; i++) {
            let dif = Math.abs(_same_cards[i] - _same_cards[i - 1]);

            if (dif > 1) empty_place += dif - 1
        }

        return empty_place
    },

    getIsPokersIsSequence:function (sameFlowerArray,mixNum) {
        let groupCards = [].concat(sameFlowerArray)

        let allSameFlowerPokers = cc.gg.tpgMgr.get13EmptyArray()
        let mixCards = []
        let firstHua

        for(let i=0;i<groupCards.length;i++){
            let card = groupCards[i]
            let num = cc.gg.dataMgr.getPokerNum(card.poker)
            let hua = cc.gg.dataMgr.getPokerHua(card.poker)

            if(cc.gg.dataMgr.isMixCard(card.poker,mixNum)){
                mixCards.push(card)
                groupCards.splice(i--,1)
                continue
            }

            if(!firstHua)
                firstHua = cc.gg.dataMgr.getPokerHua(groupCards[0].poker)

            if(firstHua && firstHua !== hua){
                cc.logcal("--不同花色，返回")
                return {
                    isSequence:false,
                    isPure:false
                }
            }

            allSameFlowerPokers[num].push(card)
            groupCards.splice(i--,1)
        }

        if(mixCards.length !== 0){
            cc.gg.tpgMgr.doMixScoreArray(allSameFlowerPokers,mixCards)
        }

        let isPure = true
        let seqCount = 0

        for(let i=0;i<allSameFlowerPokers.length;i++){

            //sequence not start
            if(!seqCount && !allSameFlowerPokers[i].length)
                continue

            //sequence's first poker
            if(!seqCount && allSameFlowerPokers[i].length){
                seqCount = 1

                if(isPure && cc.gg.dataMgr.isMixCard(allSameFlowerPokers[i][0].poker,mixNum))
                    isPure = false

                if(isPure && firstHua && cc.gg.dataMgr.getPokerHua(allSameFlowerPokers[i][0].poker) !== firstHua)
                    isPure = false

                continue
            }

            //sequence broken
            if(seqCount && !allSameFlowerPokers[i].length){
                let exsistsAfter = false
                for(let j=i+1;j<allSameFlowerPokers.length;j++){
                    if(allSameFlowerPokers[j].length){
                        exsistsAfter = true
                        break
                    }
                }

                if(exsistsAfter){
                    cc.logcal("--顺子中间断了，返回")
                    return {
                        isSequence:false,
                        isPure:isPure
                    }
                }else {
                    cc.logcal("--后面没了，检查连续牌的张数:",seqCount)
                    return {
                        isSequence:seqCount > 2,
                        isPure:isPure
                    }
                }
            }


            let tmpPokerId = allSameFlowerPokers[i][0].poker
            let num = cc.gg.dataMgr.getPokerNum(tmpPokerId)
            let hua = cc.gg.dataMgr.getPokerHua(tmpPokerId)

            if(num !== mixNum && hua !== firstHua && hua !== cc.gg.enumConfig.FLOWER.JOKER){
                cc.logcal("--这张不同花了:",cc.gg.dataMgr.getPokerName(tmpPokerId)," 返回")
                return {
                    isSequence:false,
                    isPure:isPure
                }
            }

            if(num !== mixNum && allSameFlowerPokers[i].length > 1){
                cc.logcal("--这张牌有相同的两张，而且不是混子，返回")
                return {
                    isSequence:false,
                    isPure:isPure
                }
            }

            seqCount++

            if(isPure && ((firstHua && hua !== firstHua) || mixNum === num))
                isPure = false
        }

        cc.logcal("--条件均通过，检查连续牌的张数:",seqCount)
        return {
            isSequence: seqCount > 2,
            isPure:isPure
        }
    },

    isSet:function (pokerGroup, mixNum) {
        if(pokerGroup.length < 3 || pokerGroup.length > 4){
            cc.logcal("--张数不符合规定，不是Set")
            return false
        }

        let arrayCopy = []

        //remove mix cards
        for(let i=0;i<pokerGroup.length;i++){
            if(!cc.gg.dataMgr.isMixCard(pokerGroup[i].poker,mixNum))
                arrayCopy.push(pokerGroup[i])
        }


        let allHua = []
        let allNum = []
        for(let i=0;i<arrayCopy.length;i++){
            let num = cc.gg.dataMgr.getPokerNum(arrayCopy[i].poker)
            if(num === mixNum){
                continue
            }
            allNum.push(num)

            let hua = cc.gg.dataMgr.getPokerHua(arrayCopy[i].poker)
            allHua.push(hua)
        }

        //check is all num same
        if(!cc.gg.baseUtil.arrayAllEquall(allNum)){
            cc.logcal("--除了混子以外，不是所有牌的点数都相同，不是Set")
            return false
        }

        //check if there is more than a same flower poker
        for(let i=0;i<allHua.length;i++){
            let hua = allHua[i]
            let sameHuaCount = 0

            for(let j=0;j<allHua.length;j++){
                let hua2 = allHua[j]
                if(hua2 === hua){
                    sameHuaCount++
                    if(sameHuaCount>1){
                        cc.logcal("--除了混子以外，有超过一张的同样花色，不是Set")
                        return false
                    }
                }
            }
        }


        return true
    },

    CAN_FINISH:function (cardsArray, mixNum) {

        let hasPureSeq = false
        let seqCount = 0
        let typeObjs = []
        for(let i=0;i<cardsArray.length;i++){
            let cards = cardsArray[i]
            let typeObj = this.GET_GROUP_TYPE(cards,mixNum)
            if(typeObj.isSequence){
                if(typeObj.isPure) hasPureSeq = true
                seqCount ++
            }
            typeObjs.push(typeObj)
        }
        cc.log("【判断能否Finish，typeObjs：",typeObjs)
        cc.log("【判断能否Finish，hasPureSeq:",hasPureSeq)

        let totalSum = 0
        // let invalidObjCount = 0
        if(hasPureSeq && seqCount > 1){
            cc.log("【判断能否Finish，有pure，并且有效组的数量够",seqCount)
            for(let i=0;i<typeObjs.length;i++){
                let obj = typeObjs[i]
                if(obj.isSet || obj.isSequence) {
                    cc.log("【【【【【obj.isSet || obj.isSequence",obj.isSet , obj.isSequence)
                    continue
                }
                if(!obj.isSet && !obj.isSequence){
                    // if(invalidObjCount++ > 1)
                    cc.log("【【【【【发现了既不是set也不是seq的组！不能Finish")
                    return false
                }
                // totalSum += this.GET_CARDS_SUM(obj.cards,mixNum)
                // if(totalSum > 0)
                //     return false
            }
        }else {
            cc.log("【判断能否Finish，没有pure，并且有效组的数量不够",seqCount)
            return false
        }

        cc.log("【判断能否Finish，条件都通了，能 finish  o(*￣︶￣*)o：")
        return true
    },

    GET_GROUP_TYPE:function (cardVals, mixNum) {

        let typeObj = this.IS_SEQUENCE_ONLY_VALUE(cardVals,mixNum)
        if(!typeObj.isSequence){
            let isSet = this.isSetOnlyValue(cardVals,mixNum)
            typeObj.isSet = isSet
        }
        typeObj.cards = cardVals
        return typeObj
    },

    isSetOnlyValue:function (pokerGroup, mixNum) {
        if(pokerGroup.length < 3 || pokerGroup.length > 4){
            cc.logcal("--张数不符合规定，不是Set")
            return false
        }

        let arrayCopy = []

        //remove mix cards
        for(let i=0;i<pokerGroup.length;i++){
            if(!cc.gg.dataMgr.isMixCard(pokerGroup[i],mixNum))
                arrayCopy.push(pokerGroup[i])
        }


        let allHua = []
        let allNum = []
        for(let i=0;i<arrayCopy.length;i++){
            let num = cc.gg.dataMgr.getPokerNum(arrayCopy[i])
            if(num === mixNum){
                continue
            }
            allNum.push(num)

            let hua = cc.gg.dataMgr.getPokerHua(arrayCopy[i])
            allHua.push(hua)
        }

        //check is all num same
        if(!cc.gg.baseUtil.arrayAllEquall(allNum)){
            cc.logcal("--除了混子以外，不是所有牌的点数都相同，不是Set")
            return false
        }

        //check if there is more than a same flower poker
        for(let i=0;i<allHua.length;i++){
            let hua = allHua[i]
            let sameHuaCount = 0

            for(let j=0;j<allHua.length;j++){
                let hua2 = allHua[j]
                if(hua2 === hua){
                    sameHuaCount++
                    if(sameHuaCount>1){
                        cc.logcal("--除了混子以外，有超过一张的同样花色，不是Set")
                        return false
                    }
                }
            }
        }


        return true
    }
});
